
package com.hlkj.pay.app.merchant.ext.impl.jhpay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantOrderExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.jhpay.dto.*;
import com.hlkj.pay.app.merchant.ext.impl.jhpay.handle.JhPayMerchantCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.jhpay.util.JhPaySignUtil;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.order.PayOrderChannelResultDto;
import com.hlkj.pay.dto.order.notify.CsOrderNotifyDto;
import com.hlkj.pay.dto.order.notify.RefundOrderNotifyDto;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.order.RefundOrderDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 汇付订单操作
 * 
 * @author HlpayTeam
 * @date 2024/10/10 13:51
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_JH)
public class JhPayMerchantOrderExtPt extends JhPayMerchantCommonParamsHandle implements ChannelMerchantOrderExtPt {

    private final OkHttpTemplate okHttpTemplate;

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        // 配置转换
        CommonResult<JhPayConfig> commonResult = jhPayConfig(channelPayOrderContext.getProviderChannelConfigDO(), channelPayOrderContext.isTest());
        JhPayConfig jhPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        JhPayAppChannelParams jhPayAppChannelParams = jhPayAppChannelParams(channelPayOrderContext.getMerchantAppChannelDO());
        PayWayDO payWayDO = channelPayOrderContext.getPayWayDO();
        try {
            String payUrl = payUrl(channelPayOrderContext.isTest());
            payUrl = payUrl + "/trade/submit";
            JhPayOrderReq jhPayOrderReq = new JhPayOrderReq();
            jhPayOrderReq.setMerchantNo(jhPayAppChannelParams.getMerchantNo());
            jhPayOrderReq.setOutTradeNo(payOrderDO.getPayOrderNo());
            PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(payWayDO.getType());
            PayOrderCommonParamReq.Extra extra = null;
            if (StringUtils.hasText(payOrderDO.getExtra())) {
                extra = JsonUtils.parseObject(payOrderDO.getExtra(), PayOrderCommonParamReq.Extra.class);
            }
            PayEnums.SCENE_PAY_TYPE scenePayType = PayEnums.SCENE_PAY_TYPE.fromByCode(payWayDO.getCode());
            if (scenePayType == null) {
                channelPayOrderContext.setRemark("工行支付请求失败,失败信息,当前支付当时不支持" + payType.getDesc());
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            switch (payType) {
                case WECHAT:
                    jhPayOrderReq.setPayBrand("WXPAY");
                    if (extra == null) {
                        channelPayOrderContext.setRemark("工行支付请求失败,失败信息,微信支付必填提交subAppid以及userId");
                        channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                        return;
                    }
                    if (!StringUtils.hasText(extra.getSubAppid())) {
                        channelPayOrderContext.setRemark("工行支付请求失败,失败信息,微信支付必填提交subAppid");
                        channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                        return;
                    }
                    if (!StringUtils.hasText(extra.getUserId())) {
                        channelPayOrderContext.setRemark("工行支付请求失败,失败信息,微信支付必填提交userId");
                        channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                        return;
                    }
                    Map<String, String> extendInfo = new HashMap<>();
                    extendInfo.put("wxAppId", extra.getSubAppid());
                    extendInfo.put("wxOpenId", extra.getUserId());
                    jhPayOrderReq.setExtendInfo(JsonUtils.toJsonString(extendInfo));
                    break;
                case ALIPAY:
                    jhPayOrderReq.setPayBrand("ALIPAY");
                    if (extra == null && payWayDO.getSubType().equals(PayEnums.SCENE_PAY_TYPE.JSAPI.getType())) {
                        channelPayOrderContext.setRemark("工行支付请求失败,失败信息,支付宝生活号必填提交subAppid以及userId");
                        channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                        return;
                    }
                    if (extra != null) {
                        extendInfo = new HashMap<>();
                        extendInfo.put("alipayAppId", extra.getSubAppid());
                        extendInfo.put("alipayUnionId", extra.getUserId());
                        jhPayOrderReq.setExtendInfo(JsonUtils.toJsonString(extendInfo));
                    }
                    break;
                case UNION_APY:
                    jhPayOrderReq.setPayBrand("UNIONPAY");
                    break;
                default:
                    channelPayOrderContext.setRemark("工行支付请求失败,失败信息,当前支付当时不支持" + payType.getDesc());
                    channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                    return;
            }

            jhPayOrderReq.setScanType("USM");
            switch (scenePayType) {
                case H5:
                case WAP:
                    jhPayOrderReq.setPayWayType("H5");
                    break;
                case JSAPI:
                    jhPayOrderReq.setPayWayType("JSAPI");
                    break;
                case MINI_APP:
                    jhPayOrderReq.setPayWayType("MINI_PROGRAM");
                    break;
                case APP:
                    jhPayOrderReq.setPayWayType("APP");
                    break;
                case SCAN:
                    jhPayOrderReq.setPayWayType("MICROPAY");
                    jhPayOrderReq.setScanType("MSU");
                    jhPayOrderReq.setPaymentCode(extra.getAuthCode());
                    break;
                case QR:
                    jhPayOrderReq.setPayWayType("NATIVE");
                    break;
                default:
                    channelPayOrderContext.setRemark("工行支付请求失败,失败信息,当前支付当时不支持" + payType.getDesc());
                    channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                    return;
            }
            PayOrderEnums.FUND_PROCESS_TYPE fundProcessType = PayOrderEnums.FUND_PROCESS_TYPE.from(payOrderDO.getFundProcessType());
            switch (fundProcessType) {
                case NO:
                    jhPayOrderReq.setPsType("N");
                    break;
                case REAL_TIME:
                    jhPayOrderReq.setPsType("P");
                    break;
                case DELAY_TIME:
                    jhPayOrderReq.setPsType("D");
                    break;
                default:
                    channelPayOrderContext.setRemark("工行支付请求失败,失败信息,当前分账方式不支持" + fundProcessType.getMsg());
                    channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                    return;
            }
            if (!CollectionUtils.isEmpty(channelPayOrderContext.getAccounts())) {
                List<JhPayOrderAccountReq> jhPayOrderAccountReqs = new ArrayList<>();
                channelPayOrderContext.getAccounts().stream().forEach(payOrderFundDto -> {
                    JhPayOrderAccountReq jhPayOrderAccountReq = new JhPayOrderAccountReq();
                    jhPayOrderAccountReq.setPsType(jhPayOrderReq.getPsType());
                    jhPayOrderAccountReq.setOriginalTradeNo(jhPayOrderReq.getOutTradeNo());
                    jhPayOrderAccountReq.setRequestNo(payOrderFundDto.getBatchNoDetail());
                    jhPayOrderAccountReq.setLedgerAmount(MerchantUtils.stringToFen(payOrderFundDto.getAmount()));
                    jhPayOrderAccountReq.setLedgerReceiver(payOrderFundDto.getAccountNo());
                    jhPayOrderAccountReq.setLedgerSubject(payOrderFundDto.getDescription());
                    jhPayOrderAccountReqs.add(jhPayOrderAccountReq);
                });
                jhPayOrderReq.setLedgerApplyDetail(JsonUtils.toJsonString(jhPayOrderAccountReqs));
            }
            jhPayOrderReq.setTradeAmount(MerchantUtils.YuanToFen(payOrderDO.getAmount()));
            jhPayOrderReq.setTradeSubject(payOrderDO.getSubject());
            jhPayOrderReq.setPartnerNo(jhPayConfig.getPartnerNo());
            jhPayOrderReq.setTransDate(System.currentTimeMillis() + "");
            jhPayOrderReq.setTransNonce(IdUtils.fastSimpleUUID());
            jhPayOrderReq.setNotifyUrl(channelPayOrderContext.getNotifyUrl());
            jhPayOrderReq.setSignature(JhPaySignUtil.signature(jhPayOrderReq, jhPayConfig));

            log.info("工行 提交订单支付 请求参数:{}", JsonUtils.toJsonString(jhPayOrderReq));
            String requestBody = JsonUtils.toJsonString(jhPayOrderReq);
            String post = okHttpTemplate.post(payUrl, requestBody, null);
            log.info("工行 提交订单支付 返回参数:{}", post);
            JhPayOrderSubmitRes jhPayOrderSubmitRes = JsonUtils.parseObject(post, JhPayOrderSubmitRes.class);
            if (!jhPayOrderSubmitRes.success()) {
                channelPayOrderContext.setRemark("工行支付请求失败,失败信息" + jhPayOrderSubmitRes.getMessage());
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            if (StringUtils.hasText(jhPayOrderSubmitRes.getPayUrl())) {
                channelPayOrderContext.setPayDataType("pay_url");
                channelPayOrderContext.setPayInfo(jhPayOrderSubmitRes.getPayUrl());
            }
            else {
                channelPayOrderContext.setPayDataType("data");
                channelPayOrderContext.setPayInfo(jhPayOrderSubmitRes.getFormInput());
            }
            channelPayOrderContext.setChannelOrderNo(jhPayOrderSubmitRes.getTradeNo());
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("工行 提交订单支付 请求失败 message:{}", e.getMessage(), e);
            channelPayOrderContext.setRemark("工行 提交订单支付 请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        // 配置转换
        CommonResult<JhPayConfig> commonResult = jhPayConfig(channelPayOrderQueryContext.getProviderChannelConfigDO(), channelPayOrderQueryContext.isTest());
        JhPayConfig jhPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelPayOrderQueryContext.getPayOrderDO();
        JhPayAppChannelParams jhPayAppChannelParams = jhPayAppChannelParams(channelPayOrderQueryContext.getMerchantAppChannelDO());
        try {
            String payUrl = payUrl(channelPayOrderQueryContext.isTest());
            payUrl = payUrl + "/trade/query";
            JhPayOrderReq jhPayOrderReq = new JhPayOrderReq();
            jhPayOrderReq.setMerchantNo(jhPayAppChannelParams.getMerchantNo());
            jhPayOrderReq.setOutTradeNo(payOrderDO.getPayOrderNo());
            jhPayOrderReq.setPartnerNo(jhPayConfig.getPartnerNo());
            jhPayOrderReq.setTransDate(System.currentTimeMillis() + "");
            jhPayOrderReq.setTransNonce(IdUtils.fastSimpleUUID());
            jhPayOrderReq.setSignature(JhPaySignUtil.signature(jhPayOrderReq, jhPayConfig));
            log.info("工行 查询订单支付 请求参数:{}", JsonUtils.toJsonString(jhPayOrderReq));
            String requestBody = JsonUtils.toJsonString(jhPayOrderReq);
            String post = okHttpTemplate.post(payUrl, requestBody, null);
            log.info("工行 查询订单支付 返回参数:{}", post);
            JhPayOrderQueryRes jhPayOrderQueryRes = JsonUtils.parseObject(post, JhPayOrderQueryRes.class);
            PayOrderDO updartePayOrderDO = new PayOrderDO();
            channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
            if (jhPayOrderQueryRes.success()) {
                switch (jhPayOrderQueryRes.getTradeStatus()) {
                    case "SUCCESS":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                        updartePayOrderDO.setBankMsg("");
                        break;
                    case "CLOSE":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                        break;
                    case "CANCEL":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CANCEL.getCode());
                        break;
                    default:
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                }
                if (StringUtils.hasText(jhPayOrderQueryRes.getPayFinishTime())) {
                    try {
                        updartePayOrderDO.setSuccessTime(DateUtils.shanghaiDate(jhPayOrderQueryRes.getPayFinishTime(), "yyyyMMddHHmmss"));
                    }
                    catch (Exception e) {
                        log.error("工行 查询订单支付 时间格式化错误 dateTime:{},message:{}", jhPayOrderQueryRes.getPayFinishTime(), e.getMessage());
                    }
                }
            }
            else {
                String respDesc = jhPayOrderQueryRes.getMessage();
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                if (StringUtils.hasText(respDesc)) {
                    updartePayOrderDO.setBankMsg(respDesc);
                }
                else {
                    channelPayOrderQueryContext.setRemark("工行 查询订单支付 返回错误信息为空,错误码为:" + jhPayOrderQueryRes.getCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("工行 查询订单支付请求失败 message:{}", e.getMessage(), e);
            channelPayOrderQueryContext.setRemark("工行 查询订单支付请求失败,失败信息" + e.getMessage());
            channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {

    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        // 配置转换
        CommonResult<JhPayConfig> commonResult = jhPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(), channelRefundPayOrderContext.isTest());
        JhPayConfig jhPayConfig = commonResult.getData();
        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        JhPayAppChannelParams jhPayAppChannelParams = jhPayAppChannelParams(channelRefundPayOrderContext.getMerchantAppChannelDO());
        try {
            String payUrl = payUrl(channelRefundPayOrderContext.isTest());
            payUrl = payUrl + "/trade/refund";
            JhPayRefundOrderSubmitReq jhPayOrderReq = new JhPayRefundOrderSubmitReq();
            jhPayOrderReq.setOutRefundNo(refundOrderDO.getRefundOrderNo());
            jhPayOrderReq.setOriginalTradeNo(payOrderDO.getPayOrderNo());
            jhPayOrderReq.setPartnerNo(jhPayConfig.getPartnerNo());
            jhPayOrderReq.setTransDate(System.currentTimeMillis() + "");
            jhPayOrderReq.setTransNonce(IdUtils.fastSimpleUUID());
            jhPayOrderReq.setNotifyUrl(channelRefundPayOrderContext.getNotifyUrl());
            jhPayOrderReq.setRefundAmount(MerchantUtils.bigDecimalToString(refundOrderDO.getRefundAmount()));
            jhPayOrderReq.setSignature(JhPaySignUtil.signature(jhPayOrderReq, jhPayConfig));

            log.info("工行 提交订单退款 请求参数:{}", JsonUtils.toJsonString(jhPayOrderReq));
            String requestBody = JsonUtils.toJsonString(jhPayOrderReq);
            String post = okHttpTemplate.post(payUrl, requestBody, null);
            log.info("工行 提交订单退款 返回参数:{}", post);
            JhPayRefundOrderQueryRes jhPayOrderQueryRes = JsonUtils.parseObject(post, JhPayRefundOrderQueryRes.class);

            if (jhPayOrderQueryRes.success()) {
                RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
                if ("SUCCESS".equals(jhPayOrderQueryRes.getRefundStatus())) {
                    updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                }
                else if ("FAIL".equals(jhPayOrderQueryRes.getRefundStatus())) {
                    updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                }
                else {
                    updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                }
                channelRefundPayOrderContext.setUpdateRefundOrderDO(updateRefundOrderDO);
            }
            else {
                String respDesc = jhPayOrderQueryRes.getMessage();
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(respDesc)) {
                    channelRefundPayOrderContext.setRemark(respDesc);
                }
                else {
                    channelRefundPayOrderContext.setRemark("工行 提交订单退款返回错误信息为空,错误码为:" + jhPayOrderQueryRes.getCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("工行 提交订单退款订单请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("工行 提交订单退款订单请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        // 配置转换
        CommonResult<JhPayConfig> commonResult = jhPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(), channelRefundPayOrderContext.isTest());
        JhPayConfig jhPayConfig = commonResult.getData();

        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        JhPayAppChannelParams heliPayAppChannelParams = jhPayAppChannelParams(channelRefundPayOrderContext.getMerchantAppChannelDO());
        try {
            String payUrl = payUrl(channelRefundPayOrderContext.isTest());
            payUrl = payUrl + "/trade/refundQuery";
            JhPayRefundOrderQueryReq jhPayOrderReq = new JhPayRefundOrderQueryReq();
            jhPayOrderReq.setOutRefundNo(refundOrderDO.getRefundOrderNo());
            jhPayOrderReq.setPartnerNo(jhPayConfig.getPartnerNo());
            jhPayOrderReq.setTransDate(System.currentTimeMillis() + "");
            jhPayOrderReq.setTransNonce(IdUtils.fastSimpleUUID());
            jhPayOrderReq.setSignature(JhPaySignUtil.signature(jhPayOrderReq, jhPayConfig));

            log.info("工行 查询订单退款 请求参数:{}", JsonUtils.toJsonString(jhPayOrderReq));
            String requestBody = JsonUtils.toJsonString(jhPayOrderReq);
            String post = okHttpTemplate.post(payUrl, requestBody, null);
            log.info("工行 查询订单退款 返回参数:{}", post);
            JhPayRefundOrderQueryRes jhPayOrderQueryRes = JsonUtils.parseObject(post, JhPayRefundOrderQueryRes.class);

            RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
            channelRefundPayOrderContext.setUpdateRefundOrderDO(updateRefundOrderDO);
            if (jhPayOrderQueryRes.success()) {
                switch (jhPayOrderQueryRes.getRefundStatus()) {
                    case "FAIL":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                        updateRefundOrderDO.setBankMsg(jhPayOrderQueryRes.getMessage());
                        break;
                    case "SUCCESS":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                        break;
                    default:
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                }
            }
            else {
                String respDesc = jhPayOrderQueryRes.getMessage();
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                if (StringUtils.hasText(respDesc)) {
                    updateRefundOrderDO.setBankMsg(respDesc);
                }
                else {
                    channelRefundPayOrderContext.setRemark("工行 查询订单退款返回错误信息为空,错误码为:" + jhPayOrderQueryRes.getCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("工行 查询订单退款查询请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("工行 查询订单退款请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> orderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        Map<String, String> params = HttpRequestUtil.requestFormParams(request);
        String response = JsonUtils.toJsonString(params);
        log.info("工行收到支付订单回调,参数数据为 payOrderDO:{}", response);
        CommonResult<PayOrderChannelResultDto> payOrderDOCommonResult = CommonResult.success();
        try {
            CommonResult<JhPayConfig> commonResult = jhPayConfig(providerChannelConfigDO, true);
            // 配置转换
            JhPayConfig heliPayConfig = commonResult.getData();
            boolean verify = JhPaySignUtil.verify(response, params.get("signature"), heliPayConfig.getPublicKey());
            if (!verify) {
                log.info("工行支付订单回调验签不通过,signature:{}", response);
                payOrderDOCommonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            payOrderDOCommonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
        }
        JhPayOrderQueryRes heliPayOrderQueryRes = JsonUtils.parseObject(response, JhPayOrderQueryRes.class);
        PayOrderDO updartePayOrderDO = new PayOrderDO();
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        payOrderChannelResultDto.setUpdatePayOrderDO(updartePayOrderDO);
        payOrderChannelResultDto.setCallBackBody(response);
        switch (heliPayOrderQueryRes.getTradeStatus()) {
            case "INIT":
            case "PAYING":
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                updartePayOrderDO.setBankMsg("");
                break;
            case "SUCCESS":
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                updartePayOrderDO.setBankMsg("");
                break;
            case "FAIL":
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                break;
            case "CLOSE":
                updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                break;

        }
        if (StringUtils.hasText(heliPayOrderQueryRes.getPayFinishTime())) {
            try {
                updartePayOrderDO.setSuccessTime(DateUtils.shanghaiDate(heliPayOrderQueryRes.getPayFinishTime(), "yyyyMMddHHmmss"));
            }
            catch (Exception e) {
                log.error("工行支付订单返回 时间格式化错误 dateTime:{},message:{}", heliPayOrderQueryRes.getPayFinishTime(), e.getMessage());
            }
        }
        updartePayOrderDO.setPayOrderNo(heliPayOrderQueryRes.getOutTradeNo());
        updartePayOrderDO.setChannelOrderNo(heliPayOrderQueryRes.getTradeNo());
        log.info("工行收到支付订单回调,解析后的订单数据为 payOrderDO:{}", JsonUtils.toJsonString(updartePayOrderDO));
        return payOrderDOCommonResult;
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> orderStatusParse(HttpServletRequest request) {
        return null;
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> merAuthParse(HttpServletRequest request) {
        return null;
    }

    @Override
    public PayOrderDO closeOrderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

    @Override
    public CommonResult<CsOrderNotifyDto> csOrderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

    @Override
    public CommonResult<RefundOrderNotifyDto> refundStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        Map<String, String> params = HttpRequestUtil.requestFormParams(request);
        String response = JsonUtils.toJsonString(params);
        log.info("工行收到退款订单回调,参数数据为 payOrderDO:{}", response);
        String paramsConfig = providerChannelConfigDO.getParamsConfig();
        CommonResult<RefundOrderNotifyDto> payOrderDOCommonResult = CommonResult.success();
        try {
            // 配置转换
            CommonResult<JhPayConfig> commonResult = jhPayConfig(providerChannelConfigDO, true);
            // 配置转换
            JhPayConfig heliPayConfig = commonResult.getData();
            boolean verify = JhPaySignUtil.verify(response, params.get("signature"), heliPayConfig.getPublicKey());
            if (!verify) {
                log.info("工行退款订单回调验签不通过,signature:{}", response);
                payOrderDOCommonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            payOrderDOCommonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
        }
        JhPayRefundOrderQueryRes heliPayRefundOrderQueryRes = JsonUtils.parseObject(response, JhPayRefundOrderQueryRes.class);
        RefundOrderNotifyDto refundOrderNotifyDto=new RefundOrderNotifyDto();
        refundOrderNotifyDto.setCallBackBody(response);
        RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
        refundOrderNotifyDto.setRefundOrder(updateRefundOrderDO);
        updateRefundOrderDO.setRefundOrderNo(heliPayRefundOrderQueryRes.getOutRefundNo());
        switch (heliPayRefundOrderQueryRes.getRefundStatus()) {
            case "FAIL":
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                updateRefundOrderDO.setBankMsg(heliPayRefundOrderQueryRes.getMessage());
                break;
            case "SUCCESS":
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                break;
            default:
                updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
        }
        payOrderDOCommonResult.setData(refundOrderNotifyDto);
        log.info("工行收到退款订单回调,解析后的订单数据为 payOrderDO:{}", JsonUtils.toJsonString(updateRefundOrderDO));
        return payOrderDOCommonResult;
    }

    @Override
    public String channelPayCode(PayWayDO payWayDO) {
        return payWayDO.getCode();
    }

    @Override
    public Long queryChannelPayAppid(ChannelPayOrderContext channelPayOrderContext) {
        return null;
    }
    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "SUCCESS";
        }
        else {
            return commonResult.getMsg();
        }
    }

    @Override
    public boolean wechatLink(ChannelPayOrderContext channelPayOrderContext) {
        return false;
    }
}
